package alarm;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;

import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;

import view.FrameWork;
import features.SNMPClient;
import features.SNMPException;
import features.SNMPSession;

public class SendAlarmPanel extends JPanel {
	private static final long serialVersionUID = -8852168119878870537L;
	
	private JTextField txtTargetIpAddress;
	private JComboBox cmbStartupAlarm;
	private JLabel lblTargetIpAddress;
//	private JLabel lblFallingEventIndex;
	private JLabel lblStartupAlarm;
	private JLabel lblInterval;
//	private JLabel lblRisingEventIndex;
	private JLabel lblFallingThreshold;
	private JLabel lblRisingThreshold;
	private JLabel lblSampleType;
	private JLabel lblVariable;
	private JButton bttCancel;
	private JButton bttSend;
	private JLabel lblCommunity;
	private JLabel lblDoubleDot;
	private JPanel pnlAlarmDetails;
	private JTextField txtInterval;
	private JTextField txtVariable;
	private JTextField txtRisingThreshold;
	private JPanel pnlTarget;
	private JComboBox cmbSampleType;
//	private JTextField txtFallingEventIndex;
//	private JTextField txtRisingEventIndex;
	private JTextField txtFallingThreshold;
	private JComboBox cmbCommunity;
	private JTextField txtTargetPort;

	/**
	 * This is the default constructor
	 */
	public SendAlarmPanel() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setLayout(null);
		this.setPreferredSize(new java.awt.Dimension(493, 269));
		this.add(getPnlTarget());
		this.add(getPnlAlarmDetails());
		this.add(getBttSend());
		this.add(getBttCancel());

	}

	private JPanel getPnlTarget() {
		if(pnlTarget == null) {
			pnlTarget = new JPanel();
			pnlTarget.setBorder(BorderFactory.createTitledBorder(null, "TargetHost Info", TitledBorder.LEADING, TitledBorder.TOP));
			pnlTarget.setBounds(0, 0, 493, 56);
			pnlTarget.add(getLblTargetIpAddress());
			pnlTarget.add(getTxtTargetIpAddress());
			pnlTarget.add(getLblDoubleDot());
			pnlTarget.add(getTxtTargetPort());
			pnlTarget.add(getLblCommunity());
			pnlTarget.add(getCmbCommunity());
		}
		return pnlTarget;
	}

	private JLabel getLblTargetIpAddress() {
		if(lblTargetIpAddress == null) {
			lblTargetIpAddress = new JLabel();
			lblTargetIpAddress.setText("Indirizzo IP:");
		}
		return lblTargetIpAddress;
	}

	public JTextField getTxtTargetIpAddress() {
		if (txtTargetIpAddress == null) {
			txtTargetIpAddress = new JTextField();
			txtTargetIpAddress.setPreferredSize(new java.awt.Dimension(125, 21));
//			txtTargetIpAddress.setText("192.2.1.1");
		}
	
		return txtTargetIpAddress;
	}

	private JLabel getLblDoubleDot() {
		if(lblDoubleDot == null) {
			lblDoubleDot = new JLabel();
			lblDoubleDot.setText(":");
		}
		return lblDoubleDot;
	}

	public JTextField getTxtTargetPort() {
		if (txtTargetPort == null) {
			txtTargetPort = new JTextField();
			txtTargetPort.setPreferredSize(new java.awt.Dimension(60, 21));
			txtTargetPort.setText("161");
		}
	
		return txtTargetPort;
	}

	private JLabel getLblCommunity() {
		if(lblCommunity == null) {
			lblCommunity = new JLabel();
			lblCommunity.setText("Community:");
			lblCommunity.setPreferredSize(new java.awt.Dimension(82, 14));
			lblCommunity.setHorizontalAlignment(SwingConstants.TRAILING);
		}
		return lblCommunity;
	}

	public JComboBox getCmbCommunity() {
		if (cmbCommunity == null) {
			ComboBoxModel cmbCommunityModel = new DefaultComboBoxModel(
					new String[] { "public", "private" });
			cmbCommunity = new JComboBox();
			cmbCommunity.setModel(cmbCommunityModel);
			cmbCommunity.setEditable(true);
			cmbCommunity.setPreferredSize(new java.awt.Dimension(117, 21));
		}
		
		return cmbCommunity;
	}

	private JPanel getPnlAlarmDetails() {
		if(pnlAlarmDetails == null) {
			pnlAlarmDetails = new JPanel();
			pnlAlarmDetails.setLayout(null);
			pnlAlarmDetails.setBorder(BorderFactory.createTitledBorder(null, "Dettagli alarm", TitledBorder.LEADING, TitledBorder.TOP));
			pnlAlarmDetails.setBounds(0, 72, 493, 135);
			pnlAlarmDetails.add(getLblVariable());
			pnlAlarmDetails.add(getTxtVariable());
			pnlAlarmDetails.add(getLblStartupAlarm());
			pnlAlarmDetails.add(getCmbStartupAlarm());
			
			pnlAlarmDetails.add(getLblRisingThreshold());
			pnlAlarmDetails.add(getTxtRisingThreshold());
//			pnlAlarmDetails.add(getLblRisingEventIndex());
//			pnlAlarmDetails.add(getTxtRisingEventIndex());
			
			pnlAlarmDetails.add(getLblFallingThreshold());
			pnlAlarmDetails.add(getTxtFallingThreshold());
//			pnlAlarmDetails.add(getLblFallingEventIndex());
//			pnlAlarmDetails.add(getTxtFallingEventIndex());
			
			pnlAlarmDetails.add(getLblSampleType());
			pnlAlarmDetails.add(getCmbSampleType());
			pnlAlarmDetails.add(getLblInterval());
			pnlAlarmDetails.add(getTxtInterval());
		}
		return pnlAlarmDetails;
	}

	private JLabel getLblVariable() {
		if(lblVariable == null) {
			lblVariable = new JLabel();
			lblVariable.setText("OID Variabile:");
			lblVariable.setBounds(5, 19, 117, 29);
		}
		return lblVariable;
	}

	public JTextField getTxtVariable() {
		if (txtVariable == null) {
			txtVariable = new JTextField();
			txtVariable.setBounds(120, 21, 117, 21);
			
//			txtVariable.setText(".1.3.6.1.2.1.11.1.0");
		}
	
		return txtVariable;
	}

	private JLabel getLblStartupAlarm() {
		if(lblStartupAlarm == null) {
			lblStartupAlarm = new JLabel();
			lblStartupAlarm.setText("Startup alarm");
			lblStartupAlarm.setBounds(249, 19, 117, 29);
		}
		return lblStartupAlarm;
	}

	public JComboBox getCmbStartupAlarm() {
		if (cmbStartupAlarm == null) {
			ComboBoxModel cmbStartupAlarmModel = new DefaultComboBoxModel(
					new StartupAlarm[] { StartupAlarm.risingOrFallingAlarm, StartupAlarm.risingAlarm, StartupAlarm.fallingAlarm});
			cmbStartupAlarm = new JComboBox();
	
			cmbStartupAlarm.setModel(cmbStartupAlarmModel);
			cmbStartupAlarm.setBounds(365, 21, 117, 22);
		}
	
		return cmbStartupAlarm;
	}

	private JLabel getLblRisingThreshold() {
		if(lblRisingThreshold == null) {
			lblRisingThreshold = new JLabel();
			lblRisingThreshold.setText("Soglia di salita:");
			lblRisingThreshold.setBounds(5, 53, 117, 29);
		}
		return lblRisingThreshold;
	}

	public JTextField getTxtRisingThreshold() {
		if (txtRisingThreshold == null) {
			txtRisingThreshold = new JTextField();
			txtRisingThreshold.setBounds(120, 55, 117, 21);
//			try {
//				SNMPSession session = SNMPClient.startSession(SNMPClient.VERSION_2C);
//				session.init("192.2.1.1", SNMPClient.DEFAULT_PORT_STRING, "public");
//				String value = session.getSingleValue(".1.3.6.1.2.1.11.1.0").toString();
//				int v = Integer.parseInt(value);
//				v += 200;
//				txtRisingThreshold.setText(v + "");
//			} catch (Exception e) {
//				txtRisingThreshold.setText("8000");
//			}
		}
	
		return txtRisingThreshold;
	}

//	private JLabel getLblRisingEventIndex() {
//		if(lblRisingEventIndex == null) {
//			lblRisingEventIndex = new JLabel();
//			lblRisingEventIndex.setText("Indice evento salita*:");
//			lblRisingEventIndex.setBounds(249, 53, 117, 29);
//		}
//		return lblRisingEventIndex;
//	}
//
//	public JTextField getTxtRisingEventIndex() {
//		if (txtRisingEventIndex == null) {
//			txtRisingEventIndex = new JTextField();
//			txtRisingEventIndex.setBounds(366, 55, 117, 21);
//		}
//	
//		return txtRisingEventIndex;
//	}

	private JLabel getLblFallingThreshold() {
		if(lblFallingThreshold == null) {
			lblFallingThreshold = new JLabel();
			lblFallingThreshold.setText("Soglia di discesa:");
			lblFallingThreshold.setBounds(249, 53, 117, 29);
//			lblFallingThreshold.setBounds(5, 87, 117, 29);
		}
		return lblFallingThreshold;
	}

	public JTextField getTxtFallingThreshold() {
		if (txtFallingThreshold == null) {
			txtFallingThreshold = new JTextField();
			txtFallingThreshold.setBounds(366, 55, 117, 21);
//			txtFallingThreshold.setBounds(120, 89, 117, 21);
//			txtFallingThreshold.setText("300");
		}
	
		return txtFallingThreshold;
	}

//	private JLabel getLblFallingEventIndex() {
//		if(lblFallingEventIndex == null) {
//			lblFallingEventIndex = new JLabel();
//			lblFallingEventIndex.setText("Indice evento discesa*:");
//			lblFallingEventIndex.setBounds(249, 87, 117, 29);
//		}
//		return lblFallingEventIndex;
//	}
//
//	public JTextField getTxtFallingEventIndex() {
//		if (txtFallingEventIndex == null) {
//			txtFallingEventIndex = new JTextField();
//			txtFallingEventIndex.setBounds(366, 89, 117, 21);
//		}
//	
//		return txtFallingEventIndex;
//	}

	private JLabel getLblSampleType() {
		if(lblSampleType == null) {
			lblSampleType = new JLabel();
			lblSampleType.setText("Tipo di campionamento:");
			lblSampleType.setBounds(5, 87, 117, 29);
		}
		return lblSampleType;
	}

	public JComboBox getCmbSampleType() {
		if (cmbSampleType == null) {
			ComboBoxModel cmbSampleTypeModel = new DefaultComboBoxModel(
					new SampleType[] { SampleType.absoluteValue, SampleType.deltaValue });
			cmbSampleType = new JComboBox();
			cmbSampleType.setModel(cmbSampleTypeModel);
			cmbSampleType.setBounds(120, 89, 117, 22);
//			cmbSampleType.setBounds(120, 123, 117, 22);
		}
		return cmbSampleType;
	}

	private JLabel getLblInterval() {
		if(lblInterval == null) {
			lblInterval = new JLabel();
			lblInterval.setText("Intervallo (secondi):");
			lblInterval.setBounds(249, 87, 117, 29);
//			lblInterval.setBounds(249, 121, 117, 29);
		}
		return lblInterval;
	}

	public JTextField getTxtInterval() {
		if (txtInterval == null) {
			txtInterval = new JTextField();
			txtInterval.setBounds(366, 89, 117, 21);
			txtInterval.setText("1");
		}

		return txtInterval;
	}
	
	private JButton getBttCancel() {
		if(bttCancel == null) {
			bttCancel = new JButton();
			bttCancel.setText("Annulla");
			bttCancel.setBounds(384, 230, 78, 27);
			
			bttCancel.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					close();
				}
			});
		}
		return bttCancel;
	}
	
	public JButton getBttSend() {
		if(bttSend == null) {
			bttSend = new JButton();
			bttSend.setText("Invia");
			bttSend.setBounds(294, 230, 78, 27);
			
			bttSend.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					String ip = SNMPClient.DEFAULT_IP;
					try {
						String community = (String) getCmbCommunity().getSelectedItem();
						if(community == null || community.trim().length() == 0)
							community = SNMPClient.DEFAULT_COMMUNITY;
						
						String port = (String) getTxtTargetPort().getText();
						if(port == null || port.trim().length() == 0)
							port = SNMPClient.DEFAULT_PORT_STRING;
						
						String newIp = getTxtTargetIpAddress().getText();
						try {
							String ipBytesStr[] = newIp.split("\\.");
							InetAddress.getByAddress(new byte[]{new Integer(ipBytesStr[0]).byteValue(), new Integer(ipBytesStr[1]).byteValue(), new Integer(ipBytesStr[2]).byteValue(), new Integer(ipBytesStr[3]).byteValue()});
							
							ip = newIp;
						} catch (Exception e1) {
							FrameWork.sendMessage("Indicare un indirizzo ip valido (xxx.xxx.xxx.xxx)", "Attenzione", JOptionPane.WARNING_MESSAGE);
							
							return;
						}
						SNMPSession session = SNMPClient.startSession(SNMPClient.VERSION_2C);
						session.init(ip, port, community);
						
						final Alarm alarm = createAlarm();
						AlarmRegistry.getInstance().registerAlarm(alarm);
						try {
							session.registerAlarm(alarm, new CommandResponder() {
								public void processPdu(
										CommandResponderEvent event) {
									if(AlarmRegistry.getInstance().isActive(alarm)) {
										Object source = event.getSource();

										String msg = "OID: "  + alarm.getVariable().toString(); 
										msg += "\nIP dell'Host : " + alarm.getTargetIp();
										msg += "\nSoglia discesa: " + alarm.getFallingThreshold().toInt();  
										msg += "\nSoglia salita: " + alarm.getRisingThreshold().toInt();
										msg += "\nValore attuale: " + alarm.getAlarmValue().getValue();
										
										String title = "Alarm sollevato";
										if(source instanceof String) {
											title += " in " + source;
										}
										
										FrameWork.sendMessage(msg, title, JOptionPane.INFORMATION_MESSAGE);
									}
								}
							});
						}catch (Exception exc) {
							AlarmRegistry.getInstance().unregisterAlarm(alarm);
							exc.printStackTrace();
						}
						
						close();
					} catch (SNMPException excSNMP) {
						excSNMP.printStackTrace();
						
						FrameWork.sendMessage("Impossibile stabilire una connessione.", "Errore", JOptionPane.ERROR_MESSAGE);
					} catch (Exception exc) {
						FrameWork.sendMessage(exc.getMessage(), "Errore", JOptionPane.ERROR_MESSAGE);
					}
				}
				
				private Alarm createAlarm() throws Exception {
					Alarm alarm = new Alarm();
					alarm.setStatus(AlarmStatus.valid);
					alarm.setTargetIp(getTxtTargetIpAddress().getText() + ":" + getTxtTargetPort().getText());
//					try {
//					alarm.setOwner(new OctetString("monitor"));
						alarm.setOwner(new OctetString(InetAddress.getLocalHost().getHostName()));
//						alarm.setOwner(new OctetString("monitor 192.2.1.2 163"));
//						alarm.setOwner(new OctetString("monitor " + (new IpAddress(InetAddress.getLocalHost()).toString()) + " 161"));
//					} catch (UnknownHostException exc) {
//						throw new Exception("Impossibile determinare l'indirizzo dell'host source.");
//					}
					
//					alarm.setAlarmValue(getTxtAlarmValue());
//					alarm.setVariableIndex(getTxtVariableIndex().getText());
					
					String variable = getTxtVariable().getText();
					if(variable == null || variable.trim().length() == 0)
						throw new Exception("Indicare l'OID della variabile.");
					alarm.setVariable(new OID(variable));
					
					alarm.setStartupAlarm((StartupAlarm) getCmbStartupAlarm().getSelectedItem());
					
//					try {
//						String risingEventIndexTxt = getTxtRisingEventIndex().getText();
//						if(risingEventIndexTxt != null && risingEventIndexTxt.trim().length() > 0) {
//							int risingEventIndex = Integer.parseInt(risingEventIndexTxt);
//							
//							alarm.setRisingEventIndex(new Integer32(risingEventIndex));
//						}
//					} catch (NumberFormatException exc) {
//						throw new Exception("Indice dell'evento di discesa non valido.");
//					}
					try {
						int risingThreshold = Integer.parseInt(getTxtRisingThreshold().getText());
						
						alarm.setRisingThreshold(new Integer32(risingThreshold));
					} catch (Exception exc) {
						throw new Exception("Soglia di salita non valida.");
					}
					
					try {
						int fallingThreshold = Integer.parseInt(getTxtFallingThreshold().getText());
						
						alarm.setFallingThreshold(new Integer32(fallingThreshold));
					} catch (Exception exc) {
						throw new Exception("Soglia di discesa non valida.");
					}
//					try {
//						String fallingEventIndexTxt = getTxtFallingEventIndex().getText();
//						if(fallingEventIndexTxt != null && fallingEventIndexTxt.trim().length() > 0) {
//							int fallingEventIndex = Integer.parseInt(fallingEventIndexTxt);
//							
//							alarm.setFallingEventIndex(new Integer32(fallingEventIndex));
//						}
//					} catch (Exception exc) {
//						throw new Exception("Indice dell'evento di discesa non valido.");
//					}
					
					alarm.setSampleType((SampleType) getCmbSampleType().getSelectedItem());
					
					try {
						int interval = Integer.parseInt(getTxtInterval().getText());
						
						alarm.setInterval(new Integer32(interval));
					} catch (Exception exc) {
						throw new Exception("Intervallo non valido.");
					}
					
					return alarm;
				}
				
			});
		}
		
		return bttSend;
	}
	
	public void close() {
		//Chiude il pannello
		Container container = this.getRootPane().getParent();
//		if(container != null && container instanceof JDialog) {
			((JDialog)container).dispose();
//		} else
//			container.setVisible(false);
	}
}

